﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media.Animation;
using Mammoth.Entities;
using Mammoth.Views;

namespace Mammoth.Services
{
    public class NavigationController : Mammoth.Services.IMammothNavigationService
    {
        Stack<NavigationEntity> stack;
        Panel container;
        UIElement currentView;
        private IViewFactory viewFactory;

        public NavigationController(Grid container, IViewFactory viewFactory)
        {
            this.container = container;
            this.viewFactory = viewFactory;
            stack = new Stack<NavigationEntity>();
        }

        public void NavigateBack()
        {
            if (stack.Count > 0)
            {
                var entity = stack.Pop();
                ShowAnimateCurrentUI(entity.View, entity.Arguments);
            }
        }

        public void SetDefault(Type view)
        {
            ShowAnimateCurrentUI(view, null);
        }

        public void Show(Type view, IParameterValue arguments = null)
        {
            if (currentView.GetType() == view) return;
            SaveCurrentUI();
            ShowAnimateCurrentUI(view, arguments);
        }

        private void SaveCurrentUI()
        {
            IParameterValue curArgs = null;
            var navContent = currentView as IParameterizedView;
            if (navContent != null)
                curArgs = navContent.Arguments;

            var curEntity = new NavigationEntity() { View = currentView.GetType(), Arguments = curArgs };
            stack.Push(curEntity);
        }

        private void ShowAnimateCurrentUI(Type view, IParameterValue arguments)
        {
            currentView = viewFactory.CreateByType(view);

            Storyboard fadeIn = null;

            if (container.Children.Count > 0)
            {
                fadeIn = CreateStoryboard(container.Children[0], 1, 0);
                fadeIn.Completed += (s, e) => RemoveView();
            }

            var nav = currentView as IParameterizedView;
            if (nav != null)
                nav.Arguments = arguments;
            container.Children.Insert(0, currentView);

            if (fadeIn != null)
                fadeIn.Begin();
        }

        private void RemoveView()
        {
            var ch = container.Children[container.Children.Count - 1];
            if (ch is IEventInterest)
                ((IEventInterest)ch).ReleaseHandler();
            container.Children.Remove(ch);
        }

        void fadeOut_Completed(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

        private Storyboard CreateStoryboard(UIElement view, double? from = 0, double? to = 1)
        {
            var fadeIn = new DoubleAnimation()
            {
                From = from,
                To = to,
                Duration = TimeSpan.FromMilliseconds(300)
            };
            Storyboard.SetTarget(fadeIn, view);
            Storyboard.SetTargetProperty(fadeIn, new PropertyPath(UIElement.OpacityProperty));
            var sb = new Storyboard();
            sb.Children.Add(fadeIn);
            return sb;
        }
    }
}
